package com.glkj.vipsystem.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.glkj.vipsystem.common.enums.StockApplyFormType;
import com.glkj.vipsystem.common.enums.StockRecordType;
import com.glkj.vipsystem.common.exception.BizException;
import com.glkj.vipsystem.entity.ao.GoodsAO;
import com.glkj.vipsystem.entity.ao.ShopAO;
import com.glkj.vipsystem.entity.gen.*;
import com.glkj.vipsystem.mapper.StockApplyFormMapper;
import com.glkj.vipsystem.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 出入、移库单 服务实现类
 * </p>
 *
 * @author LiMuchan
 * @since 2020-01-10
 */
@Service
public class StockApplyFormServiceImpl extends ServiceImpl<StockApplyFormMapper, StockApplyForm> implements IStockApplyFormService {

    @Resource
    private IStockApplyFormGoodsService stockApplyFormGoodsService;
    @Resource
    private IStockService stockService;
    @Resource
    private IDepotService depotService;
    @Resource
    private IStockRecordService stockRecordService;
    @Resource
    private IShopService shopService;

    /**
     * 新增出入、移库单
     *
     * @param stockApplyForm 出入、移库单信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(StockApplyForm stockApplyForm, Long actionUserId) {
        if (stockApplyForm == null) {
            throw new BizException("新增出入、移库单失败：信息错误");
        }
        if (stockApplyForm.getCompanyId() == null) {
            throw new BizException("请选公司");
        }
        stockApplyForm.setStatus(2); // 直接成功
        Integer stockApplyFormType = stockApplyForm.getType();
        Integer inShopId = stockApplyForm.getInShopId();
        Integer outShopId = stockApplyForm.getOutShopId();
        if (stockApplyFormType == null) {
            throw new BizException("类型错误");
        }
        if (stockApplyFormType == StockApplyFormType.Ruku.getType()
                && inShopId == null) {
            throw new BizException("请选择入货店铺");
        } else if (stockApplyFormType == StockApplyFormType.Chuku.getType()
                && outShopId == null) {
            throw new BizException("请选择出货店铺");
        } else if (stockApplyFormType == StockApplyFormType.Yiku.getType()
                && (inShopId == null || outShopId == null)) {
            throw new BizException("请选择出、入货店铺");
        }

        Date now = new Date();
        stockApplyForm.setCreateTime(now);
        stockApplyForm.setActionUserId(actionUserId);
        this.insert(stockApplyForm);
        List<GoodsAO> goodsList = stockApplyForm.getGoodsList();
        if (CollectionUtils.isEmpty(goodsList)) {
            throw new BizException("请添加商品");
        }
        List<StockRecord> stockRecords = new ArrayList<>();

        // 入库
        if (stockApplyFormType == StockApplyFormType.Ruku.getType()) {
            stockApplyForm.setCompanyId(goodsList.get(0).getCompanyId());
            // 添加库存
            Depot depot = depotService.selectOne(
                    new EntityWrapper<Depot>()
                            .eq("shop_id", inShopId)
                            .last("limit 1")
            );
            stockApplyForm.setVerifyTime(now);
            stockApplyForm.setVerifyUserId(actionUserId);
            stockApplyForm.setInDepotId(depot.getId());
            StringBuilder msg = new StringBuilder();
            List<Stock> stocks = new ArrayList<>();
            for (GoodsAO goodsAO : goodsList) {
                // 添加商品库存
                Stock stock = new Stock();
                stock.setShopId(inShopId);
                stock.setDepotId(depot.getId());
                stock.setGoodsId(goodsAO.getId());
                stock.setNum(goodsAO.getNum());
                if (goodsAO.getNum() <= 0) {
                    msg.append("商品[").append(goodsAO.getGoodsName()).append("]数量不正确")
                            .append("<br/>");
                }
                Stock selectOne = stockService.selectOne(
                        new EntityWrapper<Stock>()
                                .eq("goods_id", goodsAO.getId())
                                .eq("depot_id", depot.getId())
                                .eq("shop_id", depot.getShopId())
                );
                if (selectOne != null) {
                    stock.setId(selectOne.getId());
                    stock.setNum(selectOne.getNum() + stock.getNum());
                }
                stocks.add(stock);

                // 库存记录
                StockRecord sr = new StockRecord();
                sr.setShopId(stock.getShopId());
                sr.setDepotId(stock.getDepotId());
                sr.setGoodsId(stock.getGoodsId());
                sr.setNum(goodsAO.getNum());
                sr.setCreateTime(now);
                sr.setType(StockRecordType.Ruku.getType());
                sr.setFormId(stockApplyForm.getId());
                stockRecords.add(sr);
            }
            if (StringUtils.isNotBlank(msg.toString())) {
                throw new BizException(msg.toString());
            }
            stockService.insertOrUpdateBatch(stocks);
        } else if (stockApplyFormType == StockApplyFormType.Chuku.getType()) {
            // 出库
            Depot depot = depotService.selectOne(
                    new EntityWrapper<Depot>()
                            .eq("shop_id", outShopId)
                            .last("limit 1")
            );
            stockApplyForm.setOutDepotId(depot.getId());
            stockApplyForm.setVerifyTime(now);
            stockApplyForm.setVerifyUserId(actionUserId);
            stockApplyForm.setCompanyId(goodsList.get(0).getCompanyId());

            StringBuilder msg = new StringBuilder();
            List<Stock> stocks = new ArrayList<>();
            for (GoodsAO goods : goodsList) {
                if (goods.getNum() <= 0) {
                    msg.append("商品[").append(goods.getGoodsName()).append("]数量不正确")
                            .append("<br/>");
                } else {
                    Stock stock = stockService.selectOne(outShopId, depot.getId(), goods.getId());
                    if (stock == null || stock.getNum() < goods.getNum()) {
                        msg.append("商品[").append(goods.getGoodsName()).append("]库存不足")
                                .append("<br/>");
                    } else {
                        // 库存记录
                        StockRecord sr = new StockRecord();
                        sr.setShopId(outShopId);
                        sr.setDepotId(depot.getId());
                        sr.setGoodsId(goods.getId());
                        sr.setNum(goods.getNum());
                        sr.setCreateTime(now);
                        sr.setType(StockRecordType.Chuku.getType());
                        sr.setFormId(stockApplyForm.getId());
                        stockRecords.add(sr);

                        stock.setNum(stock.getNum() - goods.getNum());
                        stocks.add(stock);
                    }
                }
            }
            if (StringUtils.isNotBlank(msg.toString())) {
                throw new BizException(msg.toString());
            }
            stockService.updateBatchById(stocks);
        } else if (stockApplyFormType == StockApplyFormType.Yiku.getType()) {
            // 移库需要审核
            stockApplyForm.setStatus(1); // 待审核
            // 校验店铺是否处于同一公司
            if (inShopId.equals(outShopId)) {
                throw new BizException("入货店铺和出货店铺不能相同");
            }
            ShopAO inShop = shopService.selectById(inShopId);
            ShopAO outShop = shopService.selectById(outShopId);
            if (inShop == null || outShop == null) {
                throw new BizException("入货店铺或出货店铺不存在");
            }
            if (!inShop.getCompanyId().equals(outShop.getCompanyId())) {
                throw new BizException("入货店铺和出货店铺必须在同一个公司下");
            }
            stockApplyForm.setCompanyId(inShop.getCompanyId());
            Depot inDepot = depotService.selectOne(
                    new EntityWrapper<Depot>()
                            .eq("shop_id", inShopId)
                            .last("limit 1")
            );
            stockApplyForm.setInDepotId(inDepot.getId());
            Depot outDepot = depotService.selectOne(
                    new EntityWrapper<Depot>()
                            .eq("shop_id", outShopId)
                            .last("limit 1")
            );
            // 移库
            stockApplyForm.setOutDepotId(outDepot.getId());
            // 校验库存
            StringBuilder msg = new StringBuilder();
            List<StockApplyFormGoods> sfgList = new ArrayList<>();
            for (GoodsAO goods : goodsList) {
                if (goods.getNum() <= 0) {
                    msg.append("商品[").append(goods.getGoodsName()).append("]数量不正确")
                            .append("<br/>");
                } else {
                    Stock stock = stockService.selectOne(outShopId, outDepot.getId(), goods.getId());
                    if (stock == null || stock.getNum() < goods.getNum()) {
                        msg.append("商品[").append(goods.getGoodsName()).append("]库存不足")
                                .append("<br/>");
                    } else {
                        // 移库单-商品关联关系
                        StockApplyFormGoods sfg = new StockApplyFormGoods();
                        sfg.setGoodsId(goods.getId());
                        sfg.setNum(goods.getNum());
                        sfg.setStockApplyFormId(stockApplyForm.getId());
                        sfgList.add(sfg);
                    }
                }
            }
            if (StringUtils.isNotBlank(msg.toString())) {
                throw new BizException(msg.toString());
            }

            // 移库单-商品关联关系
            if (!sfgList.isEmpty()) {
                stockApplyFormGoodsService.insertBatch(sfgList);
            }
        }
        // 库存记录
        if (!stockRecords.isEmpty()) {
            stockRecordService.insertBatch(stockRecords);
        }
        this.updateById(stockApplyForm);
    }

    /**
     * 审核
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void audit(StockApplyForm stockApplyForm, Long verifyUserId) {
        if (stockApplyForm == null || stockApplyForm.getId() == null) {
            throw new BizException("审核失败：信息错误");
        }
        Integer status = stockApplyForm.getStatus();
        stockApplyForm = this.selectById(stockApplyForm.getId());
        if (stockApplyForm == null) {
            throw new BizException("审核失败：信息错误");
        }
        if (stockApplyForm.getType() != StockApplyFormType.Yiku.getType()) {
            throw new BizException("审核失败：只有移库单才能审核");
        }
        Date now = new Date();
        stockApplyForm.setVerifyUserId(verifyUserId);
        stockApplyForm.setVerifyTime(now);
        stockApplyForm.setStatus(status);
        this.updateById(stockApplyForm);
        List<StockApplyFormGoods> list = stockApplyFormGoodsService.selectList(
                new EntityWrapper<StockApplyFormGoods>()
                        .eq("stock_apply_form_id", stockApplyForm.getId())
        );
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<StockRecord> records = new ArrayList<>();
        List<Stock> stocks = new ArrayList<>();
        StringBuilder msg = new StringBuilder();
        for (StockApplyFormGoods goods : list) {
            // 审核成功
            if (status == 2) {
                // 校验库存
                Stock selectOne = stockService.selectOne(
                        new EntityWrapper<Stock>()
                                .eq("shop_id", stockApplyForm.getOutShopId())
                                .eq("depot_id", stockApplyForm.getOutDepotId())
                                .eq("goods_id", goods.getGoodsId())
                );
                if (selectOne == null || selectOne.getNum() < goods.getNum()) {
                    msg.append("商品库存不足")
                            .append("<br/>");
                } else {
                    // 出库库存
                    selectOne.setNum(selectOne.getNum() - goods.getNum());
                    stocks.add(selectOne);

                    // 入库库存
                    Stock inStock = stockService.selectOne(
                            new EntityWrapper<Stock>()
                                    .eq("shop_id", stockApplyForm.getInShopId())
                                    .eq("depot_id", stockApplyForm.getInDepotId())
                                    .eq("goods_id", goods.getGoodsId())
                    );
                    if (inStock == null) {
                        msg.append("入库商品不存在")
                                .append("<br/>");
                    } else {
                        inStock.setNum(inStock.getNum() + goods.getNum());
                        stocks.add(inStock);
                    }
                }

                // 审核成功 增加库存记录
                // 库存记录
                StockRecord srin = new StockRecord();
                srin.setShopId(stockApplyForm.getInShopId());
                srin.setDepotId(stockApplyForm.getInDepotId());
                srin.setGoodsId(goods.getGoodsId());
                srin.setNum(goods.getNum());
                srin.setCreateTime(now);
                srin.setType(StockRecordType.YikuRuku.getType());
                srin.setFormId(stockApplyForm.getId());
                records.add(srin);

                StockRecord srout = new StockRecord();
                srout.setShopId(stockApplyForm.getOutShopId());
                srout.setDepotId(stockApplyForm.getOutDepotId());
                srout.setGoodsId(goods.getGoodsId());
                srout.setNum(goods.getNum());
                srout.setCreateTime(now);
                srout.setType(StockRecordType.YikuChuku.getType());
                srin.setFormId(stockApplyForm.getId());
                records.add(srout);
            }
        }
        if (StringUtils.isNotBlank(msg.toString())) {
            throw new BizException("审核失败：" + msg.toString());
        }
        if (!records.isEmpty()) {
            stockRecordService.insertBatch(records);
        }
        if (!stocks.isEmpty()) {
            stockService.updateBatchById(stocks);
        }
    }
}
